/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.metasketch.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.metasketch.reflection.RefUtil;
import org.metasketch.reflection.ReflectionAnalyser;

/**
 * 
 * @author guilhermegrg
 */
public class IdDatabase {

	RefUtil util = new RefUtil();

	Map<String, CommonIdentified> nodesPerId = new HashMap<String, CommonIdentified>();

	public void storeNode(CommonIdentified node) {
		List<CommonIdentified> processed = new ArrayList<CommonIdentified>();
		try {
			storeNode(node, processed);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected void storeNode(CommonIdentified node,
			List<CommonIdentified> processed) throws Exception {
		// TODO add reflection here, be carefull of circular references -
		// maintain a list of processed nodes...

		if (processed.contains(node))
			return;

		processed.add(node);

		List<String> simpleFields = ReflectionAnalyser.getObjectFieldNames(node
				.getClass());
		for (String string : simpleFields) {
			Object value = util.getValue(node, string);
			if (value instanceof CommonIdentified)
				storeNode((CommonIdentified) value, processed);
		}

		List<String> collections = ReflectionAnalyser
				.getNonNativeCollections(node.getClass());
		for (String string : collections) {
			Collection value = (Collection) util.getValue(node, string);
			for (Object object : value) {
				if (object instanceof CommonIdentified)
					storeNode((CommonIdentified) object, processed);
			}
		}

		if (nodesPerId.keySet().contains(node.getId())) {
			System.err.println("Duplicate! Node with id " + node.getId()
					+ " already exists!");
			return;
		}

		nodesPerId.put(node.getId(), node);
	}

	public void removeNode(CommonIdentified node) {
		removeNode(node.getId());
	}

	public void removeNode(String id) {
		nodesPerId.remove(id);
	}

	public CommonIdentified getById(String id) {
		return nodesPerId.get(id);
	}

	public CommonIdentified getByPartialId(String id) {
		Set<String> keys = nodesPerId.keySet();
		for (String key : keys) {
			if (key.startsWith(id))
				return nodesPerId.get(key);
		}

		return null;

	}

	public Collection<CommonIdentified> getNodes() {
		return nodesPerId.values();
	}

	public boolean isEmpty() {
		return nodesPerId.isEmpty();
	}

}
